package com.xiaoshuidi.cloud.gateway.filter.appversion;

import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.gateway.config.AppVersionProperties;
import com.xiaoshuidi.cloud.gateway.util.WebFrameworkUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Objects;

@Component
@RequiredArgsConstructor
public class AppVersionCheckFilter implements GlobalFilter, Ordered {
    private final AppVersionProperties appVersionProperties;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if (appVersionProperties.getCheck() && !CollectionUtils.isEmpty(appVersionProperties.getCheckPath())) {
            String appVersion = request.getHeaders().getFirst("AppVersion");
            return appVersionProperties.getCheckPath().stream()
                    .filter(p -> StringUtils.hasText(p.getPath()))
                    .filter(p -> request.getURI().getRawPath().startsWith(p.getPath()))
                    .map(p -> {
                        // 具体路径指定版本
                        if (!CollectionUtils.isEmpty(p.getVersion()) && p.getVersion().contains(appVersion)) {
                            return WebFrameworkUtils.writeJSON(exchange, CommonResult.error(406001001, p.getMessage()));
                        }
                        // 是小程序版本号, 没有限制小程序版本, 通过
                        if (StringUtils.hasText(appVersion) && appVersion.startsWith("miniapp") && (CollectionUtils.isEmpty(appVersionProperties.getVersions())
                                || appVersionProperties.getVersions().stream().noneMatch(v -> v.startsWith("miniapp")))) {
                            return chain.filter(exchange);
                        }
                        // 没有版本号 或 有限制版本号的返回错误
                        if (!StringUtils.hasText(appVersion)
                                || (!CollectionUtils.isEmpty(appVersionProperties.getVersions()) && appVersionProperties.getVersions().contains(appVersion))
                        ) {
                            return WebFrameworkUtils.writeJSON(exchange, CommonResult.error(406001001, p.getMessage()));
                        }
                        return null;
                    })
                    .filter(Objects::nonNull)
                    .findFirst().orElse(chain.filter(exchange));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
